package org.xw.service.impl;

import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.xw.dto.ManagerCheckDto;
import org.xw.dto.UserDto;
import org.xw.mapper.ManagerCheckMapper;
import org.xw.mapper.ManagerMapper;
import org.xw.mapper.UserMapper;
import org.xw.pojo.ManagerCheckPojo;
import org.xw.pojo.UserPojo;
import org.xw.service.ManagerService;
import org.xw.utils.JWTUtil;
import org.xw.utils.MD5Util;
import org.xw.utils.RedisTagUtil;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
public class ManagerServiceImpl implements ManagerService {
    private static final String MANAGER_PRE_NAME = "管理员";
    private static final String AUTHORIZATION = "Authorization";
    private static final String JWT_MANAGER_ID = "manager_id";


    @Autowired
    ManagerMapper mapper;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    ManagerCheckMapper checkMapper;

    @Autowired
    UserMapper userMapper;

    private ValueOperations getStringOps() {
        return redisTemplate.opsForValue();
    }


    /**
     * 传入用户数据进行管理员 Manager 的注册
     *
     * @param user 注册信息
     * @return 是否成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer signManager(UserPojo user) {
        Integer managerExist = mapper.isManagerExist(user.getPhone());
        if (managerExist == 0) {
            try {
                String password = MD5Util.md5(user.getPassword());//将传入的注册密码加密
                user.setPassword(password);
                Boolean result = mapper.managerSign(user);
                if (result) {
                    Integer id = user.getId();
                    String managerName = MANAGER_PRE_NAME + id;
                    UserPojo userPojo = new UserPojo();
                    userPojo.setId(id);
                    userPojo.setUsername(managerName);
                    Boolean isSuccess = mapper.updateManagerName(userPojo);
                    if (isSuccess) {
                        return 1;//注册成功并且设置了默认昵称
                    } else {
                        throw new Exception("创建默认昵称失败!");
                    }
                } else {
                    throw new Exception("注册失败！");
                }
            } catch (Exception e) {
                e.printStackTrace();
                return 2;//注册失败
            }
        } else return 0;//正在注册的电话号码已经被注册过了
    }

    /**
     * 传入登录的电话号码 phone，密码 password 进行登录
     *
     * @param phone
     * @param password
     * @return
     */
    @Override
    public HashMap managerLogin(String phone, String password) {
        UserPojo login = mapper.login(phone);
        HashMap<Object, Object> map = new HashMap<>();
        if (login != null) {
            String loginPassword = login.getPassword();
            String md5Password = MD5Util.md5(password);
            if (loginPassword.equals(md5Password)) {
                HashMap<String, String> hashMap = new HashMap<>();
                hashMap.put(JWT_MANAGER_ID, String.valueOf(login.getId()));
                hashMap.put("phone", login.getPhone());
                String token = JWTUtil.getToken(hashMap);

                ValueOperations stringOps = getStringOps();
                stringOps.set(RedisTagUtil.MANAGER_LOGIN_KEY + login.getId(), token);

                map.put("token", token);
                return map;
            } else return null;
        } else return map;
    }

    /**
     * 头像审核 传入审核对象，包含用户id userId，审核内容 checkContent，审核员 operate_manager，是否同意申请 is_approve，操作时间 operate_time
     * 同意后 将审核内容 checkContent更新到对应申请用户的头像位置
     *
     * @param managerCheck
     * @return
     */
    @Override
    public Integer agreeChangeHeadImage(ManagerCheckPojo managerCheck, HttpServletRequest request) {
        String managerIdStringFrom = JWTUtil.analyzeToken(request, AUTHORIZATION, JWT_MANAGER_ID);
        if (managerIdStringFrom != null) {
            managerCheck.setOperateManager(managerIdStringFrom);
            managerCheck.setOperateTime(LocalDateTime.now());
            String isApprove = managerCheck.getIsApprove();
            if (isApprove.equals("1")) {//1，审核通过
                try {
                    Boolean result = checkMapper.agreeHeadImageChange(managerCheck);
                    if (result) {
                        Boolean isSuccess = checkMapper.updateUserHeadImage(managerCheck);
                        if (isSuccess) {
                            return 1;//审核通过，且将头像数据更新到对应用户处
                        } else {
                            throw new Exception("审核通过，但用户头像更新失败");
                        }
                    } else {
                        throw new Exception("审核通过，但数据库修改失败");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return 2;//审核操作失败
                }
            } else {//传入结果非1，审核不通过
                Boolean result = checkMapper.agreeHeadImageChange(managerCheck);
                if (result) {
                    return 1;
                } else return 2;
            }
        } else
            return 0;//请求头未携带token
    }

    /**
     * 封禁用户  传入用户信息，将该用户封禁或者解禁
     *
     * @param user 需要解封或者封禁的用户信息
     * @return 是否封禁或解封成功
     */
    @Override
    public Boolean isBanUser(UserDto user) {
        return mapper.banUser(user);
    }

    /**
     * 审核请求列表   查看数据库中所有审核请求
     *
     * @param checkType 审核请求类型， 0：查询所有， 1,2,3.。。：查询对应类型审核请求
     * @return 审核请求数据
     */
    @Override
    public List<ManagerCheckDto> checkList(Integer checkType) {
        List<ManagerCheckPojo> managerChecks = checkMapper.checkList(checkType);
        List<ManagerCheckDto> checks = new ArrayList<>();
        for (ManagerCheckPojo managerCheck : managerChecks) {
            ManagerCheckDto dto = ManagerCheckDto.toManagerCheck(managerCheck);
            UserDto userInfo = userMapper.getUserInfo(managerCheck.getUserId());
            dto.setUserInfo(userInfo);
            String operateManager = managerCheck.getOperateManager();
            if (operateManager != null) {
                UserDto managerInfo = userMapper.getUserInfo(Integer.valueOf(operateManager));
                dto.setOperateManagerInfo(managerInfo);
            }

            checks.add(dto);
        }
        return checks;
    }
}
